package cn.dakaqi.services.impl;

import cn.dakaqi.entities.PinganOpen;
import cn.dakaqi.entities.user.VolunteerInsurance;
import cn.dakaqi.pingan.entities.ActivateResult;
import cn.dakaqi.pingan.util.PingAnUtil;
import cn.dakaqi.qnzyz.BHAccesssToken;
import cn.dakaqi.qnzyz.BHConstant;
import cn.dakaqi.qnzyz.BHInsurance;
import cn.dakaqi.qnzyz.BHMemberService;
import cn.dakaqi.services.PinganInsuranceService;
import cn.dakaqi.services.PinganOpenService;
import cn.dakaqi.services.user.VolunteerInsuranceService;
import cn.dakaqi.util.ConfigUtil;
import cn.dakaqi.utils.Clock;
import cn.dakaqi.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * @author chunyang on 2016/4/19.
 */
@Component(value = "pinganInsuranceService")
@Transactional
@Slf4j
public class PinganInsuranceServiceImpl implements PinganInsuranceService
{
    @Autowired
    BHConstant bhConstant;
    @Resource
    private PinganOpenService pinganOpenService;
    @Resource
    private VolunteerInsuranceService volunteerInsuranceService;
    @Resource
    private BHMemberService bhMemberService;
    @Resource
    private PingAnUtil pingAnUtil;
    @Autowired
    BHAccesssToken bhAccesssToken;


    /**
     * 保存用户信息，领取保险
     *
     * @param param 用户信息
     * @return Vo
     */
    @Override
    public JsonResult createInsurance(PinganOpen param)
    {
        JsonResult jsonResult = new JsonResult();

        //检查年龄段是否合法
        JsonResult checkResult = checkVolunteerAge(param);
        if (checkResult.getCode() == JsonResult.CODE_FAIL)
        {
            return checkResult;
        }

        param.setCreateTime(Clock.DEFAULT.getCurrentDate());
        param.setStatus(0);
        param.setActivateSn("");
        param.setSn("");

        //保存用户信息
        PinganOpen pinganOpen = null;
        if(null != param.getIdCard() && !"null".equals(param.getIdCard().toLowerCase()) && StringUtils.isNotBlank(param.getIdCard()))
        {
            pinganOpen = pinganOpenService.findByIdCard(param.getIdCard());
        }
        else
        {
            pinganOpen = pinganOpenService.findByGuardianIDCard(param.getGuardianIDCard());
        }

        if(null == pinganOpen)
        {
            pinganOpen = pinganOpenService.save(param);
        }

        VolunteerInsurance volunteerInsurance;
        try
        {
            //查询北航库中是否已有些用户保险信息
            volunteerInsurance = getVolunteerInsurance(pinganOpen);
            if(null != volunteerInsurance)
            {
                jsonResult.setCode(JsonResult.CODE_SUCCESS);
                jsonResult.setData(volunteerInsurance);
                return jsonResult;
            }

            //领取保险
            checkResult = getBH(pinganOpen);
            if (checkResult.getCode() == JsonResult.CODE_FAIL)
            {
                return checkResult;
            }

            //查询北航库中是否已有些用户保险信息,整合返回信息
            volunteerInsurance = getVolunteerInsurance(pinganOpen);
            jsonResult.setCode(JsonResult.CODE_SUCCESS);
            jsonResult.setMessage("OK");
            jsonResult.setData(volunteerInsurance);

        }
        catch (Exception e)
        {
            log.error("", e);
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage("Error");
        }

        return jsonResult;
    }

    /**
     * 注册平安账号并激活
     *
     * @param volunteerCode 用户编码
     * @return Vo
     */
    @Override
    public JsonResult activityPingan(String volunteerCode,String callBackPath,String customerCode)
    {

        JsonResult jsonResult = new JsonResult();

        PinganOpen param = pinganOpenService.findByVolunteerCode(volunteerCode);

        String platform = param.getPlatform();
        try
        {

            //判断开户
            PinganOpen pinganOpen = checkPinganUser(param, platform,customerCode);

            if(null == pinganOpen)
            {
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("数据无效");
                return jsonResult;
            }
            //判断激活状态 未激活则激活
            if (pinganOpen.getStatus() == PinganOpen.STATUS_NO)
            {
                //激活
                ActivateResult activateResult = pingAnUtil.activateCard(platform, pinganOpen.getVolunteerCode(), pinganOpen.getCardNum(),callBackPath);
                if (null != activateResult && "00".equals(activateResult.getState()))
                {
                    pinganOpen.setStatus(PinganOpen.STATUS_YES);
                    this.pinganOpenService.save(pinganOpen);
                    if(StringUtils.isNotBlank(activateResult.getReturnUrl()))
                    {
                        jsonResult.setCode(JsonResult.CODE_SUCCESS);
                        jsonResult.setMessage(activateResult.getReturnUrl());
                        return jsonResult;
                    }
                    else
                    {
                        jsonResult.setCode(2);
                        jsonResult.setMessage(pinganOpen.getVolunteerCode()+";"+pinganOpen.getCardNum());
                        return jsonResult;
                    }
                }
                else
                {
                    jsonResult.setCode(2);
                    jsonResult.setMessage(pinganOpen.getVolunteerCode()+";"+pinganOpen.getCardNum());
                    return jsonResult;
                }
            }
            else
            {
                jsonResult.setCode(2);
                jsonResult.setMessage(pinganOpen.getVolunteerCode()+";"+pinganOpen.getCardNum());
                return jsonResult;
            }
//
//            //整理保单信息并返回
//            VolunteerInsurance volunteerInsurance = volunteerInsuranceService.findByVolunteerCode(pinganOpen.getVolunteerCode());
//
//            PinganResponseVo pinganResponseVo = PinganResponseVo.build(pinganOpen.getName(), volunteerInsurance.getInsuranceNo(), volunteerInsurance.getPeriodStart(), volunteerInsurance.getPeriodEnd(), pinganOpen.getCardNum());
//            //执行购买保险操作后，返回我的保单页面
//            jsonResult.setCode(JsonResult.CODE_SUCCESS);
//            jsonResult.setData(pinganResponseVo);

        } catch (Exception e)
        {
            e.printStackTrace();
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage(e.getMessage());
        }
        return jsonResult;
    }

    /**
     * 判断是否开户
     *
     * @param param    开户账户
     * @param platform 平台编码
     * @return 开户账户
     * @throws Exception 开户一场
     *                   <p/>
     *                   根据之前逻辑在用户领取保险时并不会将用户信息存储至数据库，所以这里要查询在数据库中是否存在不存在就代表没有在平安注册过。
     *                   现在我改成在用户领取保险是就将用户信息保存在数据库中，但不去平安注册。所以在这里直接去平安注册。不做数据库用户的校验。
     */
    private PinganOpen checkPinganUser(PinganOpen param, String platform,String customerCode) throws Exception
    {
        PinganOpen pinganOpen = null;
//        if (param.getGuardianIDCard() == null || "".equals(param.getGuardianIDCard())) {
//            pinganOpen = pinganOpenService.findByVolunteerCode(param.getVolunteerCode());
//        } else {
//            pinganOpen = pinganOpenService.findByMobileAndIdCard(param.getGuardianMobile(), param.getGuardianIDCard());
//        }
//        if (pinganOpen == null) {
        log.info("param------->" + param);
        if (param.getCardNum() == null || param.getCardNum().equals("") || param.getCardNum().toLowerCase().equals("null"))
        {
            pinganOpen = pingAnUtil.regAccount(customerCode,param.getMemberCode(), platform, param.getVolunteerCode(), param.getName(), param.getIdCard(),
                    param.getMobile(), param.getGuardianName(), param.getGuardianMobile(), param.getGuardianIDCard());
        } else
        {
            pinganOpen = param;
        }

//        }
        return pinganOpen;
    }

    /**
     * 整合保险&平安账户信息
     *
     * @param pinganOpen 用户信息
     * @return 保险&平安账户信息Vo
     * @throws Exception 获取保险信息异常
     */
    private VolunteerInsurance getVolunteerInsurance(PinganOpen pinganOpen) throws Exception
    {
        //检查本地是否已有当前用户的保险
        log.info("pinganOpen.getVolunteerCode()-------->" + pinganOpen.getVolunteerCode());
        VolunteerInsurance volunteerInsurance = volunteerInsuranceService.findByVolunteerCodeAndStatus(pinganOpen.getVolunteerCode(), VolunteerInsurance.STATUS_ACTIVATION);

        if(null != volunteerInsurance)
        {
            log.info(volunteerInsurance.toString());
            return volunteerInsurance;
        }

        //检查北航是否已有当前用户的保险
        BHInsurance bhInsurance = bhMemberService.getVolunteerInsurance(pinganOpen.getVolunteerCode());
        if (null == bhInsurance)
            return null;
        else
        {
            //保单信息保存到自己数据库
            volunteerInsurance = new VolunteerInsurance(pinganOpen.getVolunteerCode(), bhInsurance.getInsuranceNo());
            volunteerInsurance.setPeriodStart(bhInsurance.getPeriodStart());
            volunteerInsurance.setPeriodEnd(bhInsurance.getPeriodEnd());
            volunteerInsurance.setServiceProvider(bhInsurance.getServiceProvider());
            volunteerInsurance.setServiceProviderUrl(bhInsurance.getServiceProviderUrl());
            volunteerInsurance.setStatus(VolunteerInsurance.STATUS_ACTIVATION);
            volunteerInsurance = volunteerInsuranceService.save(volunteerInsurance);
            log.info(volunteerInsurance.toString());
            return volunteerInsurance;
        }
    }

    /**
     * 校验用户年龄
     *
     * @param param 用户信息
     * @return 校验结果
     */
    private JsonResult checkVolunteerAge(PinganOpen param)
    {
        JsonResult jsonResult = new JsonResult();
        PinganOpen guardianPinganOpen;

        if (null == param.getGuardianIDCard()|| "".equals(param.getGuardianIDCard()) || "null".equals(param.getGuardianIDCard()) )
        {
            int age = getAge(param.getIdCard());
            if (age == 0 || age < 7 || age > 70)
            {
                //投保人年龄不符合条件
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("投保人年龄不符合条件");
                return jsonResult;
            }

        }
        else
        {
//            guardianPinganOpen = pinganOpenService.findByIdCard(param.getGuardianIDCard());
//
//            if (guardianPinganOpen == null)
//            {
//                //用户锁定失败
//                jsonResult.setCode(JsonResult.CODE_FAIL);
//                jsonResult.setMessage("监护人不存在");
//                return jsonResult;
//            }
//
//            if (param.getGuardianIDCard().equals(guardianPinganOpen.getGuardianIDCard()))
//            {
//                //监护人身份信息错误
//                jsonResult.setCode(JsonResult.CODE_FAIL);
//                jsonResult.setMessage("监护人身份信息错误");
//                return jsonResult;
//            }

            int age = getAge(param.getGuardianIDCard());
            if (age == 0 || age < 18 || age > 70)
            {
                //监护人年龄不符合条件
                jsonResult.setCode(JsonResult.CODE_FAIL);
                jsonResult.setMessage("监护人年龄不符合条件");
                return jsonResult;
            }
        }
        jsonResult.setCode(JsonResult.CODE_SUCCESS);
        return jsonResult;
    }

    /**
     * 领取保险
     *
     * @param pinganOpen 用户信息
     * @return 领取信息
     * @throws Exception 领取异常
     */
    private JsonResult getBH(PinganOpen pinganOpen) throws Exception
    {

        JsonResult jsonResult = new JsonResult();
        PinganOpen guardianPinganOpen = null;
        if (null == pinganOpen.getGuardianIDCard() || "".equals(pinganOpen.getGuardianIDCard()) || "null".equals(pinganOpen.getGuardianIDCard()) )
        {
            guardianPinganOpen = pinganOpenService.findByIdCard(pinganOpen.getIdCard());
        }
        else
            guardianPinganOpen = pinganOpenService.findByGuardianIDCard(pinganOpen.getGuardianIDCard());


        //领取保险
        String token = bhAccesssToken.getAccessToken(ConfigUtil.getClientId());

//        //如果已购买过保险直接返回保险信息
//        VolunteerInsurance checkInsurance = volunteerInsuranceService.findByVolunteerCode(pinganOpen.getVolunteerCode());
//        if (checkInsurance != null)
//        {
//            jsonResult.setCode(JsonResult.CODE_SUCCESS);
//            jsonResult.setMessage("OK");
//            jsonResult.setData(checkInsurance);
//            return jsonResult;
//        }

        boolean flag = bhMemberService.lockInfo(token, pinganOpen.getVolunteerCode(),
                guardianPinganOpen == null ? pinganOpen.getName() : guardianPinganOpen.getName(),
                guardianPinganOpen == null ? pinganOpen.getIdCard() : guardianPinganOpen.getIdCard(), "CID",
                guardianPinganOpen == null ? pinganOpen.getMobile() : guardianPinganOpen.getMobile(), "8000");

        if (!flag)
        {
            //用户锁定失败
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage("用户锁定失败");
            return jsonResult;
        }

        int resultCode = bhMemberService.applyInsurance(getApplyEncryption(
                guardianPinganOpen == null ? pinganOpen.getMobile() : guardianPinganOpen.getMobile(),
                guardianPinganOpen == null ? pinganOpen.getName() : guardianPinganOpen.getName(),
                guardianPinganOpen == null ? pinganOpen.getIdCard() : guardianPinganOpen.getIdCard(), "CID",
                System.currentTimeMillis(), 12, pinganOpen.getVolunteerCode()));

        if (resultCode != 0)
        {
            //保险领取失败
            jsonResult.setCode(JsonResult.CODE_FAIL);
            jsonResult.setMessage("保险领取失败");
            return jsonResult;
        }
        jsonResult.setCode(JsonResult.CODE_SUCCESS);
        return jsonResult;
    }

    /**
     * 根据身份证计算年龄（周岁）
     *
     * @param id 身份证ID
     * @return 年龄
     */
    private int getAge(String id)
    {
        Calendar ca = Calendar.getInstance();
        int nowYear = ca.get(Calendar.YEAR);
        int nowMonth = ca.get(Calendar.MONTH) + 1;
        int len = id.length();
        if (len == 18)
        {
            int IDYear = Integer.parseInt(id.substring(6, 10));
            int IDMonth = Integer.parseInt(id.substring(10, 12));
            if ((IDMonth - nowMonth) > 0)
            {
                return nowYear - IDYear - 1;
            } else
                return nowYear - IDYear;
        } else
        {
            System.out.println("错误的身份证号");
        }
        return 0;
    }

    /**
     * 拼接领取保险参数字符串
     *
     * @param phone         手机号
     * @param name          姓名
     * @param idCard        证件号
     * @param cardType      证件类型
     * @param startDate     保单生效日期
     * @param longTime      保期
     * @param volunteerCode 用户编码
     * @return 拼接成功后字符串
     */
    private String getApplyEncryption(String phone, String name, String idCard, String cardType, long startDate, int longTime, String volunteerCode)
    {
        //手机号|姓名|证件号|证件类型|保单生效日期|保期|volunteerCode
        //13541123339|张三|654023197912214345|CID|20151001 154100|13|31-00000018-8
        //其中：保单生效日期格式为yyyyMMdd HHmmss；保期 以月为单位

        DateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");

        return phone + "|" + name + "|" + idCard + "|" + cardType + "|" + sdf.format(new Timestamp(startDate)) + "|" + longTime + "|" + volunteerCode;
    }
}
